using System;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;


public class HttpWebRequestDownloadHandler : DownloadHandlerScript
{
    private string m_SavePath;
    private FileStream m_FileStream;
    
    public HttpWebRequestDownloadHandler(string savePath)
    {
        var dir = Path.GetDirectoryName(savePath);
        Directory.CreateDirectory(dir);
        
        m_SavePath = savePath;
        m_FileStream = new FileStream(m_SavePath, FileMode.Append, FileAccess.Write);
    }

    protected override bool ReceiveData(byte[] data, int dataLength)
    {
        m_FileStream.Write(data, 0, dataLength);
        return true;
    }

    public override void Dispose()
    {
        base.Dispose();
        DisposFileStream();
    }

    private void DisposFileStream()
    {
        Logger.Log($"[HttpWebRequestDownloadHandler](DisposFileStream) {m_SavePath}");
        if (m_FileStream != null)
        {
            m_FileStream.Flush();
            m_FileStream.Dispose();
        }
        m_FileStream = null;
    }
}

public class HttpWebRequestDownloader
{
    private string m_Url;
    private string m_SavePath;
    private string m_TmpPath;
    private UnityWebRequest m_UnityWebRequest;
    private Action<HttpWebRequestDownloader> m_CompleteCallback;

    public HttpWebRequestDownloader(Action<HttpWebRequestDownloader> callback)
    {
        m_CompleteCallback = callback;
    }

    public void Start(string url, string savePath)
    {
        m_Url = url;
        m_SavePath = savePath;
        m_TmpPath = savePath + ".tmp";
        Logger.Log($"[HttpWebRequestDownloader](Start) {url} --> {m_TmpPath}");
        m_UnityWebRequest = new UnityWebRequest(m_Url, "Get", new HttpWebRequestDownloadHandler(m_TmpPath), null);
        var asyncOperation = m_UnityWebRequest.SendWebRequest();
        asyncOperation.completed += OnComplete;
    }

    private void OnComplete(AsyncOperation asyncOperation)
    {
        var webRequestAsyncOperation = asyncOperation as UnityWebRequestAsyncOperation;
        
        if (webRequestAsyncOperation.isDone)
        {
            Logger.Log($"[HttpWebRequestDownloader](OnComplete) isDone File.Move to {m_SavePath}");
            if (File.Exists(m_SavePath))
            {
                File.Delete(m_SavePath);
            }
            File.Move(m_TmpPath, m_SavePath);
        }
        else
        {
            Logger.Log($"[HttpWebRequestDownloader](OnComplete) File.Delete {m_TmpPath}");
            if (File.Exists(m_TmpPath))
            {
                File.Delete(m_TmpPath);
            }
        }
        m_CompleteCallback?.Invoke(this);
    }
}